﻿// <copyright file="HandTracking.cs" company="Ucaya">
// </copyright>
// <author>Ucaya</author>

namespace KinectExtensions.Controls
{
    #region

    using System.ComponentModel;
    using System.ComponentModel.Composition;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;

    using KinectExtensions.Nui;
    using KinectExtensions.Services;

    using DesignerProperties = KinectExtensions.DesignerProperties;

    #endregion

    public class HandTracking : Control
    {
        #region Constants and Fields

        /// <summary>
        ///   IsHandOver depedency property.
        /// </summary>
        public static readonly DependencyProperty IsHandOverProperty = DependencyProperty.Register("IsHandOver", typeof(bool), typeof(HandTracking), null);

        /// <summary>
        ///   Position depedency property.
        /// </summary>
        public static readonly DependencyProperty PositionProperty = DependencyProperty.Register("Position", typeof(Point), typeof(HandTracking), null);

        public static readonly DependencyProperty RelativePositionProperty = DependencyProperty.Register("RelativePosition", typeof(Point), typeof(HandTracking), null);

        #endregion

        #region Constructors and Destructors

        static HandTracking()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(HandTracking), new FrameworkPropertyMetadata(typeof(HandTracking)));
        }

        public HandTracking()
        {
            if (DesignerProperties.IsInDesignTool)
            {
                return;
            }
            ServiceLocator.Instance.SatisfyImportsOnce(this);
            this.HandTrackingService.MasterPositionChanged += this.HandTrackingService_MasterPositionChanged;
        }

        #endregion

        #region Public Properties

        [Import]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public HandTrackingService HandTrackingService { get; set; }

        public bool IsHandOver
        {
            get
            {
                return (bool)this.GetValue(IsHandOverProperty);
            }

            set
            {
                this.SetValue(IsHandOverProperty, value);
            }
        }

        public Point Position
        {
            get
            {
                return (Point)this.GetValue(PositionProperty);
            }

            set
            {
                this.SetValue(PositionProperty, value);
            }
        }

        public Point RelativePosition
        {
            get
            {
                return (Point)this.GetValue(RelativePositionProperty);
            }
            set
            {
                this.SetValue(RelativePositionProperty, value);
            }
        }

        #endregion

        #region Methods

        private void HandTrackingService_MasterPositionChanged(object sender, RelativePositionEventArgs e)
        {
            if (e.Position == null)
            {
                this.IsHandOver = false;
            }
            else
            {
                Window h = Application.Current.MainWindow;
                if (h != null)
                {
                    var positionInWindow = new Point(h.ActualWidth * e.Position.Value.X, h.ActualHeight * e.Position.Value.Y);
                    GeneralTransform transform = h.TransformToVisual(this);
                    Point localPosition = transform.Transform(positionInWindow);
                    this.Position = localPosition;
                    this.RelativePosition = new Point(localPosition.X / this.ActualWidth, localPosition.Y / this.ActualHeight);
                }
            }
        }

        #endregion

        // Using a DependencyProperty as the backing store for RelativePosition.  This enables animation, styling, binding, etc...
    }
}